/***************************************************************************
 创建者: 华磊
 开始时间: 2019.3.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2017.5.8 类的具体实现代码编写

 ***************************************************************************
 *  @file x.h
 *  功能:
 *
 *                                                                         *
 ***************************************************************************/
#ifndef FLEETSERVICE_H
#define FLEETSERVICE_H

#include <QObject>
#include "MacroDefine/GeneralDefine.h"
#include "fleetdefine.h"
#include <QQueue>
#include <QMutex>
#include <queue>

class PowerManager;
#ifdef D_USE_ROS
class PathPlanManager;
#endif
class FleetTextCommandTransfer;

class FleetService : public QObject
{
    Q_OBJECT
public:
    explicit FleetService(PowerManager *powerManageIn,QObject *parent = nullptr);

public:
    int addMonitorDi_fleet(bool isOr,QVector<int> diIndex,QVector<int> diValue);
    int getTrigPosition(QQueue<PointPro> &trigPoseOut);
    int resetScanTrigPoseGetFlag();
    bool getScantrigPoseGetFlag();
    int stopMotionTrig(int doIndex);//结束触发
    int setMotionTrigPara(int doIndex,double trigPeriod);//开始触发
    int setPathAuthority(QVector<int> pathListIn, QVector<int> stationAuthorityListIn);
    int getBarrierRunMode(E_BARRIER_RUN_MODE &modeOut);
    int getBarriorDetectMode(E_BARRIER_TETECT_MODE &modeOut);
    int setCurrentVehicleBorderId(struct UserInfo userInfo,int idIn);
    int getCurrentVehicleBorderId(struct UserInfo userInfo,int &idOut);
    int shutDownAgvSystem(UserInfo userInfo);

    EN_CONTROL_TYPE getRunModel();
    int getRollerMechanismStatus(enum E_ROLLER_STATUS &statusOut);
    int  getLiftMechanismStatus(enum E_LIFT_STATUS &statusOut);

    int setVehicleBorderOffset(struct UserInfo userInfo,double front_offsetIn,double back_offsetIn,
                               double left_offsetIn,double right_offsetIn);
    int setBarrierRunMode(struct UserInfo userInfo,E_BARRIER_RUN_MODE modeIn);
    int clearFleetCommandQueue();
    int getFleetCommandQueue(QQueue<FleetCommand> &fleetCommandQueueOut);
    int clearErrorAndRestoreRun(UserInfo userInfo);
    int getCurrentFloorId();
    int getMapVersion();
    int errorNotice();
    int getCurrentFleetMap( std::string &mapInfoReturn);
    int getFleetMap(std::string mapNameIn, std::string &mapInfoReturn);
    int writeFleetMap(std::string mapNameIn, std::string &mapInfoIn);
    int loadMap(std::string mapPathIn);

    int setDoVector(unsigned short doListIn,unsigned short doValidMask);
    unsigned short getDi_short(int shortIndex);//返回１６ｂｉｔｄｉ
    unsigned short getDo_short(int shortIndex);//返回１６ｂｉｔｄo
    int setFleetTextCommandMaxLogLine(int maxIn);
    int getCurrentMapName(string &mapNameOut);
    int getPathMovingInfo(PathMovingInfo &infoOut);
    int getFleetCommandLog(std::queue<string> &fleetCommandLogOut);
    int executeTexCommand(UserInfo userInfo,QString txtCommandIn);
    int executeTexCommandList(UserInfo userInfo, QStringList txtCommandIn, int errorLineOut);
    int getMotionServerInfo(UserInfo userInfo,UpdateDataLv2 &updateDataLv2);
    /**
     * @brief getTargetPositionDistanceLeft
     * @param lineDistance  mm
     * @param angleDistance degree
     * @return
     */
    int getTargetPositionDistanceLeft(double &lineDistance,double &angleDistance);
    int getMessageInfoCode(int &errorCode,int &warnCode,int &noticeCode);
    int getFleetDebugInfo(FleetDebugInfo &infoOut);
    int pause(UserInfo userInfo);
    int stop(UserInfo userInfo);
    int stop();
    int run(UserInfo userInfo);
    int startInternalProgram(UserInfo userInfo);
    int ceaseInternalProgram(UserInfo userInfo);
    int stopInternalProgram(UserInfo userInfo);
    int setRegisterValue(UserInfo userInfo,int typeIn,int index,int subIndex,double valueIn);
    int setVisionTrigObjectLength(UserInfo userInfo,int visionIndex,double lengthIn);
    int loadInternalProgram(UserInfo userInfo, string programName);
    int getCurrentAgvPosition(UserInfo userInfo,VehiclePosition &positionOut);
    int getCurrentAgvState(UserInfo userInfo,E_AGV_STATE &stateOut);
    int getLoadedState(UserInfo userInfo,bool &stateOut);
    int getBatteryInfo(UserInfo userInfo,BatteryInformation &batteryInfoOut);
    int getCurrentAgvSpeed(UserInfo userInfo,double &lineSpeed,double &rotateSpeed);
    int getAllMessage(UserInfo userInfo,QStringList &messageListOut);
    int clearCommand(UserInfo userInfo);//完全等效stop（）
    int addRobotArmMove(UserInfo userInfo,RobotArmMoveParameter paraIn);
    int addLaserPath(UserInfo userInfo,LaserPathParameter paraIn);
    int addMaganeticPath(UserInfo userInfo,MaganeticPathParameter paraIn);
    int addRoller(UserInfo userInfo,RollerParameter paraIn);
    int addLifter(UserInfo userInfo,LiftParameter paraIn);
    int addWait(UserInfo userInfo);
    int addCharge(UserInfo userInfo,ChargeParameter paraIn);
    int addMusic(UserInfo userInfo,MusicParameter paraIn);//play now
    int addLoadMap(UserInfo userInfo,LoadMapParameter paraIn);
    int addSetGlobalVelocity(UserInfo userInfo,double velIn);//立刻生效
    int addClearMessage(UserInfo userInfo);//立刻生效
    int addAutoDrive(UserInfo userInfo,AutoDriveParameter paraIn);//不允许缓冲。执行完成１条后，再加入。
    int addWaitDi(UserInfo userInfo,WaitDiParameter paraIn);
    int addSetDo(UserInfo userInfo,SetDoParameter paraIn);


signals:

public slots:

private:

    int checkAuthority(UserInfo userInfo);
    int processWaitInstruction();
    int processWaitDiInstruction(const WaitDiParameter &paraIn);
    int processSetDoInstruction(const SetDoParameter &paraIn);
    int processMusicInstruction(const MusicParameter &musicParaIn);
    int processMapInstruction(const LoadMapParameter &mapParaIn);
    int processChargeInstruction(const ChargeParameter &chargeParaIn);
    int processLiftInstruction(const LiftParameter &liftParaIn);
    int processRollerInstruction(const RollerParameter &rollerParaIn);
    int processMaganeticInstruction(const MaganeticPathParameter &maganeticPathParaIn);
//    int processNavLineContinusInstruction(const QVector<int> &lineList,
//                             const QVector<LaserPathParameter> &laserPathListParaIn,int isLastPointMove);
    int addMotionInstruction_multiMove(const QVector<int> &lineList,
                                       const QVector<LaserPathParameter> &laserPathListParaIn);//not used
    int taskLoop();
    int trafficLoop();
    int checkEngineStatus();//防止算法模块状态意外切换到停止。
    int getCommandFromQueue(FleetCommand & moveParameter);
    int getCommandQueueSize();
    int processQueue();
    QString  longTimeToTimeString(long timeIn);
//    int isMotionInstructionFinished(int waitLine);
    int quitClear();
    int initialConfigFile_fleet(QString configFileName, QString &commentOut);
    int readConfigFile_mc(QString fileName);

    void* threadRun(void *);
    static void* threadTask( void* classPtr );
    void createThread();

    void* threadRun_traffic(void *);
    static void* threadTask_traffic( void* classPtr );
    void createThread_traffic();

    void addMsg(int messageLevel,
                 std::string componentName,
                 std::string messageType,
                 int messageCode,
                 int robotId,
                 int parameter1 = 0,
                 int parameter2 = 0,
                 int parameter3 = 0,
                 int parameter4 = 0 , QString strIn="");

private:
    bool isInitialOk;//
    pthread_t threadId;
    int robotId;
    PowerManager *powerManage;
    E_FLEET_TASK_STATUS taskStatus;//调度任务状态
    bool isInCharging;//与充电桩对接好后打开此标志位
    bool isAgvLoaded;//是否裝載了貨物
    //设计一个结构体，调度命令用队列缓存。
    QQueue<FleetCommand> fleetCommandQueue;
    QMutex queueMutex;
    float currentProcessCommandIndex;//0还没开始处理　+0.2正在处理，+0.9已经完成
    MotionDebugInfo motionDebugInfo;
    double agv_lineMaxAcceleration;
    double agv_rotateMaxAcceleration;
    double vmark_lineAcceleration;
    double vmark_rotateAcceleration;
    double cu1PositionAllowAngleAccuracy;
    int errorCode;
    bool isLoopIdile;
    UserInfo userInfo;
    int commandIndex;//从０开始，算法比较以来，用于判断行号。每次清零会导致行号判断出错。
    int executingLine;//正在执行的行。
    E_FLEET_COMMAND executingCommandType;
//    bool waitFlag;
    FleetTextCommandTransfer *txtCommandTransfer;
#ifdef D_USE_ROS
    PathPlanManager *pathPlanManager;
#endif

    PathMovingInfo pathMovingInfo;
    AutoDriveParameter currentAutoDrive;

    QVector<int> pathAuthorityList;
    QVector<int> stationAuthorityList;
    QMutex pathAuthorityMutex;
    bool isUsePathAuthority;
    bool trafficCeaseFlag;
    bool scantrigPoseGetFlag;

};

#endif // FLEETSERVICE_H
